package com.asa.control_theory.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.asa.control_theory.utils.bean.ASA_Dshape;
import com.asa.control_theory.utils.bean.ASA_Matrix;
import com.asa.hutils.MathHUtils;
import com.asa.hutils.Ni;
import com.asa.hutils.teizheng.structure.Matrix;
import com.asa.numanaly.F;
import com.asa.numanaly.I;
import com.asa.utils.Calculate;

/**
 * 
 *	对于控制论的一些矩阵的生产和运算
 *	由于有一些是矩阵的内容，但感觉别的地方没有用到这里的专门在控制论里面的东西，所以先写在这里
 *	以后在看需求来换地方吧
 * 
 */
public class MatrixUtils {
	


	/**
	 * 	范德蒙(Vandemone)矩阵			特征值重根和特征值为复数还没有
	 * @param a 矩阵
	 * @return 范德蒙(Vandemone)矩阵
	 */
	public static double[][] Vandemone(double[][] a){
		
		double[] juzhengtezhengzhi = MathHUtils.juzhengtezhengzhi(a);
		System.out.println("特征值是");
		for (int i = 0; i < juzhengtezhengzhi.length; i++) {
			System.out.println(juzhengtezhengzhi[i]);
		}
		
		double[][] result = MathHUtils.get0(a.length);
		//这个步骤可以处理好非重根的，无法处理重根的情况
//		for (int i = 0; i < result.length; i++) {
//			for (int j = 0; j < result[i].length; j++) {
//				result[i][j] = Math.pow(juzhengtezhengzhi[j], i);
//			}
//		}
		
		//处理重根的
		Map<Integer, Integer> ischong_index = weizhi_dijichonggen(juzhengtezhengzhi);

		
		for (int i = 0; i < result.length; i++) {
			for (int j = 0; j < result[i].length; j++) {
				Integer chong = ischong_index.get(j);
				if (chong!=null) {
					int[] zhishu_dao = zhishu_dao(i, chong);
					result[i][j] = zhishu_dao[0]*Math.pow(juzhengtezhengzhi[j], zhishu_dao[1]);
				}else {
					result[i][j] = Math.pow(juzhengtezhengzhi[j], i);
				}
				
			}
		}
		
		
//		Set<Entry<Double, Integer>> entrySet = count.entrySet();
//		Iterator<Entry<Double, Integer>> iterator = entrySet.iterator();
//		while (iterator.hasNext()) {
//			Entry<Double, Integer> next = iterator.next();
//			System.out.println(next.getKey()+"   :   "+next.getValue());
//			
//		}
		
		Set<Entry<Integer, Integer>> entrySet = ischong_index.entrySet();
		Iterator<Entry<Integer, Integer>> iterator = entrySet.iterator();
		while (iterator.hasNext()) {
			Entry<Integer, Integer> next = iterator.next();
			System.out.println(next.getKey()+"   :   "+next.getValue());
			
		}

		
//		MathHUtils.print(result);
		
		return result;
	}


	/**
	 * 	记录重根位置，并记录指定位置上是第几重
	 * @param juzhengtezhengzhi
	 * @return
	 */
	public static Map<Integer, Integer> weizhi_dijichonggen(double[] juzhengtezhengzhi) {
		Map<Integer,Integer> ischong_index = new HashMap<Integer,Integer>();//记录重根位置，并记录指定位置上是第几重
		Map<Double,Integer> count = new HashMap<Double, Integer>();
		for (int i = 0; i < juzhengtezhengzhi.length; i++) {
			Double d = juzhengtezhengzhi[i];
			
			if (count.containsKey(d)) {
				Integer ci = count.get(d);
				ci++;
				ischong_index.put(i, ci);
				count.put(d, ci);
			}else {
				count.put(d, 0);
			}
			
		}
		return ischong_index;
	}
	

	/**
	 * 指数函数的求导后参数
	 * @param cishu 指数函数的次数
	 * @param dao_jie	求导的阶数
	 * @return 一个数组，第一个存参数，第二个存次数
	 */
	public static int[] zhishu_dao(int cishu,int dao_jie) {
		int result_cansu=0;
		int result_cishu=0;
		if (cishu<dao_jie) {
			result_cansu = 0;
		}else{
			result_cansu = Calculate.ni_jiecheng(cishu,cishu-dao_jie);
			result_cishu = cishu - dao_jie;
		}
		
		
		int[] result = new int[2];
		result[0] = result_cansu;
		result[1] = result_cishu;
		return result ;
		
	}
	
	
	public static double sk(double rk,double rk_1,double rk_2) {
		
		double sk = rk - (rk-rk_1)*(rk-rk_1)/(rk-2*rk_1+rk_2);
		
		
		
		return sk;
		
	}
	
	
	
	/**
	 * 将矩阵转化成约旦标准型的变换矩阵	求解
	 * @throws Exception 
	 * 没做完，思路乱了
	 * 
	 */
	public static void Jordan_transform_matrix() throws Exception{
		double[][] a = {{0,0,-1},
				{3,1,3},
				{1,0,2}};
		
		
//		double[] juzhengtezhengzhi = MathHUtils.juzhengtezhengzhi(a);
//		
//		MathHUtils.print(juzhengtezhengzhi);
		
//		a = MathHUtils.zhuanzhi(a);
////		a = MathHUtils.reverse_hang(a);
//		
//		
//		double[][] copy_a = new double[a.length][a.length * 2];
//		for (int i = 0; i < copy_a.length; i++) {
//			for (int j = 0; j < copy_a.length; j++) {
//				
//				copy_a[i][j] = a[i][j];
//
//			}
//		}
//		
//		
//		
//		for (int i = 0; i < copy_a.length; i++) {
//			for (int j = copy_a.length; j < copy_a.length * 2; j++) {
//				// //System.out.println(i+" "+j);
//				if ((j - copy_a.length) == i) {
//					copy_a[i][j] = 1;
//				} else {
//					copy_a[i][j] = 0;
//				}
//
//			}
//		}
//		
//		
//		
//		
//		MathHUtils.print(copy_a);
//
//		
//		double[][] ni = Ni.getNi(copy_a);
//
//		System.out.println("矩阵的逆：");
//		MathHUtils.print(ni);

		
//		double[][] jisuan = new double[a.length*2][a.length];
//		
//
//		for (int i = 0; i < a.length; i++) {
//			for (int j = 0; j < a[i].length; j++) {
//				jisuan[i][j] = a[i][j];
//			}
//		}
//		
//		for (int i = a.length; i < jisuan.length; i++) {
//			jisuan[i][i-a.length] = 1;
//		}
//		
//		
//		MathHUtils.print(jisuan);

		
		
//		double[][] juzhengtezhengxiangliang = MathHUtils.juzhengtezhengxiangliang(a,juzhengtezhengzhi);
//		MathHUtils.print(juzhengtezhengxiangliang);
		
		
		
		
		double[][] vandemone = Vandemone(a);
		
		MathHUtils.print(vandemone);
		
		
	}
	
	
	
	
	
	
	
	
	public static void main(String[] args) throws Exception {

		
//		Jordan_transform_matrix();
		
		
		
				vandemone_test();
		
//		double jindu = 0.00001;
//		
////		double[][] a = {{2,0,0},
////				{0,3,0},
////				{0,0,1}};
//		
//		double[][] a = {{1,1,1},
//				{1,2,10},
//				{1,10,100}};
//		
////		double[][] a = {{6,5,-5},
////				{2,6,-2},
////				{2,5,-1}};
////		double[][] a = {{0,1,0},
////				{0,0,1},
////				{-6,-11,-6}};
//		
////		double[][] chenfa = MathHUtils.chenfa(MathHUtils.zhuanzhi(a), a);
////		MathHUtils.print(chenfa);
//
//		
//		
//		Vandemone(a);
//
//		double[][] tezhengzhi5_gai = I.tezhengzhi5_gai(a);
//		
//		
//		
//		Vandemone(tezhengzhi5_gai);
//		System.out.println("===================");
//		ASA_Matrix m = null;
//		ASA_Matrix m2 = null;
//
//	    int aa[]={0,0,3,3};
//	    double data[] = {1.0,-1.414213562373095,0,
//	    		-1.414213562373095,61.000000000000014,-49.0 ,
//	    		0,-49.0 ,40.99999999999999  };
//
//	    ASA asa = new ASA();
//	    
//	    ASA_Dshape dshape = new ASA_Dshape();
//	    dshape.shape = new int[4];
//	    asa.initDshape(dshape,aa);
//	    
//	    m = asa.creatMatrixFromDatas(data,9,dshape);
//	    asa.printarray(m);
//	    System.out.println();
//
//	    m2 = asa.getSymmetricMatrixEigen(m);
//	    System.out.println(m2==null);
//	    asa.printarray(m2);
//	    System.out.println();	
	    
	    
	    
	    
//		
//		
////		double[] x0 = {-1,1,1};
////
////		List<double[]> asa = new ArrayList<double[]>();
////
////		double[] result = chengfa(a, x0);
////		asa.add(result);
////
////		int index = 0;
////		
////		List<Double> r = new ArrayList<Double>();
////		List<Double> sklist = new ArrayList<Double>();
////
////		double tezhengzhi1 = 0;
////		while (true) {
////			result = chengfa(a, result);
////
////			asa.add(result);
////
////			for (int i = 0; i < result.length; i++) {
////				System.out.println(result[i]);
////			}
////			index++;
////			if (index==1000) {
////				throw new RuntimeException("超出了迭代计算上限："+1000);
////			}
////			
////			if (asa.size()>2) {
////				r.add(asa.get(asa.size()-1)[1]/asa.get(asa.size()-2)[1]);
////			}
////			if (r.size()>3) {
////				double sk = sk(r.get(r.size()-1), r.get(r.size()-2), r.get(r.size()-3));
////					
////				sklist.add(sk);
////			
////			}
////
////			if (r.size()>2) {
////				double bb = r.get(r.size()-1) - r.get(r.size()-2);
//////				System.out.println(bb+"    "+jindu);
////				
////				if (Math.abs(bb)<jindu) {
////					tezhengzhi1 = r.get(r.size()-1);
////					break;
////				}
////				
////			}
////
////			
////		}
////		System.out.println(tezhengzhi1);

		

		
		
		
		
		
		
		
		
		
		
		
		
		
		
	}


	private static double[] chengfa(double[][] a, double[] x0) {
		double[] result = new double[x0.length];

		for (int i = 0; i < a.length; i++) {
			double[] ds = a[i];
			double asa = 0;
			for (int j = 0; j < x0.length; j++) {
				asa += ds[j]*x0[j];
			}
			
			result[i] = asa;
		}
		
		double d = Math.abs(result[0]);
		for (int i = 0; i < result.length; i++) {
			result[i] = result[i]/d;
		}
		
		return result;
	}
	
	
	
	
	
	


	/**
	 * 范德蒙矩阵生成的函数测试
	 * @throws Exception
	 */
	private static void vandemone_test() throws Exception {
		System.out.println("ok");
//		double[][] a = {{0,1,0},
//				{0,0,1},
//				{-6,-11,-6}};
//		double[][] a = {{2,0,0},
//				{0,5,0},
//				{0,0,3}};
		double[][] a = {{-3,0,0},
				{0,-2,0},
				{0,0,-2}};
		
		double[][] vandemone = Vandemone(a);
		System.out.println(123);
		double[][] juzhengni = MathHUtils.juzhengni(vandemone);
		MathHUtils.print(vandemone);

		
		double[][] chenfa = MathHUtils.chenfa(juzhengni, a);
		double[][] chenfa2 = MathHUtils.chenfa(chenfa, vandemone);
//		for (int i = 0; i < chenfa2.length; i++) {
//			for (int j = 0; j < chenfa2.length; j++) {
//				if (i!=j) {
//					chenfa2[i][j] = 0.0001;
//				}
//			}
//		}
		
		
		
		double[]  juzhengtezhengzhi= MathHUtils.juzhengtezhengzhi(chenfa2);
		System.out.println();
		MathHUtils.print(chenfa2);
		for (int i = 0; i < juzhengtezhengzhi.length; i++) {
			System.out.println(juzhengtezhengzhi[i]);
		}
	}
	
	
	
	
	
	
	
	
	
	
}
